接下來,假如我們讓 Container 也可以是 Component ,那就意味著這兩件事都可以達成:
樹狀結構不用多說,就是 Container 裡面可以含有 Container,這是 Tab / Expand / Column 這類 Component 的基礎。
預留位置則可以做到讓後面執行的指令在前面插入新的 Component :
a := AddContainer(root, "placeholder1")
Text(root, "Line1")
Text(a, "This line will appear at the top of Line1")
在前一章,我們其實已經幫 Container 準備好結構了,
Package 加入新的函數,讓使用者可以在一個 Container 裡面加一個新的 Container:
func AddContainer(c *Container, id string) *Container {
nc := NewContainer(id)
c.Comps = append(c.Comps, nc)
return nc
}
Frontend 端需要把原本沒有遞迴結構改成這樣子:
createComponent
根據 comp.type 選擇呼叫的 create functioncreateContainer
底下會去呼叫 createComponent 來建立 sub componentsfunction createButton(comp) {...}
function createText(comp) {...}
function createContainer(comp) {
const cont = document.createElement('div')
comp.comps.forEach(comp => {
cont.appendChild(createComponent(comp))
})
return cont
}
function createComponent(comp) {
if (comp.type === 'container') {
return createContainer(comp)
} else if (comp.type === 'button') {
return createButton(comp)
} else if (comp.type === 'text') {
return createText(comp)
} else {
throw new Error('comp type: `' + comp.type + '` undefined')
}
}
然後在 Call API 的地方呼叫 createComponent
fetch('/api/run').then(resp => resp.json()).then(root => {
const root = document.getElementById("root")
root.innerHTML = ''
root.appendChild(createComp(root))
})
結果: